package com.healthySys.backend.controller;


import com.healthySys.backend.service.UserPOService;
import com.healthySys.common.entity.UserPO;
import com.healthySys.common.result.Result;
import com.healthySys.common.utils.JWTStoreUtil;
import com.healthySys.common.utils.UserContextUtil;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.authentication.*;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;

import java.util.Map;
import java.util.Set;

@RequiredArgsConstructor
@RestController
@RequestMapping("/sys")
@Slf4j
public class SysController {

    private final AuthenticationManager authenticationManager;
    @Resource
    private final UserContextUtil userContextUtil;
    @Resource
    private final JWTStoreUtil jwtStoreUtil;
    @Resource
    private UserPOService userPOService;

    @PostMapping("/login")
    public Result<String> login(@RequestBody Map<String, String> credentials) {


        String username = credentials.get("username");
        String password = credentials.get("password");
        log.info("{}:正在登录", username);
        try {
            //使用身份验证管理器验证用户 并获取该用户
            Authentication authentication = authenticationManager.authenticate(
                    new UsernamePasswordAuthenticationToken(username, password)
            );

            //强制退出原来的登录用户
            if (jwtStoreUtil.containUser(username)) { //判断 redis中是否存在该用户
                Map<String, String> securityContext = userContextUtil.getALlSecurityContext(); //获取 安全上下文容器
                String oldToken = jwtStoreUtil.getJWTByUsername(username); //获取该用户的现在的Token

                //从 安全容器上下文 和 redis 中移除原来的用户
                jwtStoreUtil.removeStoredJWT(username);
                securityContext.remove(username);
                log.info("用户名:{}:token:{}原先的登录已被退出", username, oldToken);
            }

            String token = JWTStoreUtil.createJWT(username); //为新登录的用户创建新Token

            jwtStoreUtil.storeJWT(username, token, JWTStoreUtil.EXPIRATION_MS); //存储JWT 实现单点登录

            SecurityContextHolder.getContext().setAuthentication(authentication); //将用户信息(username)存入安全上下文容器
            log.info("用户:{} 登录成功", username);

            return Result.success("the token of " + username, token);
        } catch (BadCredentialsException e) {
            log.warn("用户 {} 登录失败: 用户名或密码错误", username);
            return Result.error(401, "用户名或密码错误");

        } catch (LockedException e) {
            log.warn("用户 {} 登录失败: 账户已被锁定", username);
            return Result.error(401, "账户已被锁定");

        } catch (DisabledException e) {
            log.warn("用户 {} 登录失败: 账户已被禁用", username);
            return Result.error(401, "账户已被禁用");

        } catch (AuthenticationException e) {
            log.warn("用户 {} 登录失败: {}", username, e.getMessage());
            return Result.error(401, "登录失败");
        }
    }
    //@PreAuthorize("hasAuthority('user:add')") //使用权限限制
    @PreAuthorize("hasRole('ROLE_ADMIN')") //使用角色限制
    @GetMapping("/active-user")
    public Result getActiveUsers() {
        log.info("正在尝试查询已登录用户");
        return Result.success(userContextUtil.getRedisContext());
    }

    @PreAuthorize("hasRole('ROLE_ADMIN')")
    @PostMapping("/disabled-user")
    public Result<Void> setUserDisabled(Integer id) {
        String currentUsername = userContextUtil.getCurrentUsername(); // 获取当前操作用户信息
        UserPO userPO = userPOService.getById(id); // 查询目标用户
        if (userPO == null) return Result.error(404, "用户不存在"); // 用户不存在直接返回错误结果
        
        log.info("{} 正在尝试禁用目标用户: {}", currentUsername, userPO.getUsername()); // 记录日志：当前用户尝试禁用目标用户

        // 使用Wrapper更新用户状态
        boolean updated = userPOService.update(userPO, new com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper<UserPO>()
                .eq("id", id)
                .set("enable", false)); // 使用Wrapper构建更新条件

            return Result.success("用户禁用成功");

    }


}
